<?php

namespace App\Services;

use App\Libraries\BaiduQianfan;
use App\Libraries\Claude;
use App\Libraries\GeMini;
use App\Libraries\Gpt;
use BadMethodCallException;

class AiChatService
{
    protected $model;

    public function __construct($model)
    {
        $this->model = $model;
    }

    public function sendMessage($messages)
    {
        try {
            $model = $this->model;
            if (method_exists($this, $model)) {
                return call_user_func_array([$this, $model], [$messages]);
            } else {
                throw new BadMethodCallException("Method $model does not exist.");
            }
        } catch (\Exception $e) {
            return false;
        }
    }

    public function countTokens($messages)
    {
        try {
            $model = $this->model;
            if (method_exists($this, $model)) {
                return call_user_func_array([$this, $model], [$messages, true]);
            } else {
                throw new BadMethodCallException("Method $model does not exist.");
            }
        } catch (\Exception $e) {
            return false;
        }
    }

    private function gemini($messages, $count_tokens = false)
    {
        $service = new GeMini;
        if ($count_tokens) {
            $response = $service->count_tokens($messages);
            return $response['totalTokens'];
        } else {
            $response = $service->run($messages);
            $finish_reason = $response['candidates'][0]['finishReason'];
            return [
                'err_code' => $finish_reason == 'STOP' ? 0 : -1,
                'content' => $response['candidates'][0]['content']['parts'][0]['text'],
                'total_token' => $response['usageMetadata']['totalTokenCount'],
                'finish_reason' => $finish_reason, //STOP为正常 MAX_TOKENS为超出限制
            ];
        }

    }

    private function gpt($messages)
    {
        $response = (new Gpt())->run($messages);
        $finish_reason = $response['choices'][0]['finish_reason'];
        return [
            'err_code' => $finish_reason == 'stop' ? 0 : -1,
            'content' => $response['choices'][0]['message']['content'],
            'total_token' => $response['usage']['total_tokens'],
            'finish_reason' => $response['choices'][0]['finish_reason'] // stop为正常，length为超出限制
        ];
    }

    private function claude($messages)
    {
        $response = (new Claude())->run($messages);
        $finish_reason = $response['stop_reason'];
        return [
            'err_code' => 0,
            'content' => $response['content'][0]['text'],
            'total_token' => $response['usage']['input_tokens'] + $response['usage']['output_tokens'],
            'finish_reason' => $finish_reason
        ];
    }

    private function qianfan($messages)
    {
        $response = (new BaiduQianfan())->run($messages);
        if (isset($response['error_code']) && $response['error_code'] != 0) {
            return [
                'err_code' => -1
            ];
        }
        return [
            'err_code' => 0,
            'content' => $response['result'],
            'total_token' => $response['usage']['total_tokens'],
            'finish_reason' => $response['finish_reason']
        ];
    }
}
